/*
 * Copyright (C) 2004-2008 Geometer Plus <contact@geometerplus.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

#include "HtmlDescriptionReader.h"
#include <stdio.h>
#include <string.h>

HtmlDescriptionReader::HtmlDescriptionReader(BookDescription &description) : HtmlReader(description.encoding()), myDescription(description) {
	myDescription.title().erase();

#ifdef DBG_LOG
	dbg = fopen("/mnt/ext2/fbreader.log","at");
	if(dbg) {
		fprintf(dbg,"==========================================================================\n");
		fprintf(dbg,"file: %s\n",description.fileName().c_str());
		fprintf(dbg,"encoding: %s\n",description.encoding().c_str());
	}
#endif
}

void HtmlDescriptionReader::startDocumentHandler() {
	myReadTitle = false;
}

void HtmlDescriptionReader::endDocumentHandler() {
	if (!myDescription.title().empty()) {
		const char *titleStart = myDescription.title().data();
		const char *titleEnd = titleStart + myDescription.title().length();
		std::string newTitle;
		myConverter->convert(newTitle, titleStart, titleEnd);
		myDescription.title() = newTitle;
	}
}

bool HtmlDescriptionReader::tagHandler(const HtmlTag &tag) {
#ifdef DBG_LOG
	if(dbg) {
		fprintf(dbg,"tag: %s\n",tag.Name.c_str());
	}
#endif

	if (tag.Name == "TITLE") {
		myReadTitle = tag.Start && myDescription.title().empty();
		return true;
	}
	// get encoding from page header
	if (tag.Name == "META") {
		for (size_t i=0; i<tag.Attributes.size(); ++i) {
#ifdef DBG_LOG
			if(dbg) {
				fprintf(dbg,"attribute: '%s' = '%s'\n",tag.Attributes[i].Name.c_str(),(tag.Attributes[i].HasValue?tag.Attributes[i].Value.c_str():"<none>"));
			}
#endif

			if (tag.Attributes[i].Name == "HTTP-EQUIV" && tag.Attributes[i].HasValue && strcasecmp(tag.Attributes[i].Value.c_str(),"Content-Type")==0) {
				for (i=0; i<tag.Attributes.size(); ++i) {
#ifdef DBG_LOG
					if(dbg) {
						fprintf(dbg,"> attribute: '%s' = '%s'\n",tag.Attributes[i].Name.c_str(),(tag.Attributes[i].HasValue?tag.Attributes[i].Value.c_str():"<none>"));
					}
#endif

					if (tag.Attributes[i].Name == "CONTENT" && tag.Attributes[i].HasValue) {
						std::string	s1 = tag.Attributes[i].Value;
						std::string::size_type	pos = s1.find("charset=");
						if (pos == std::string::npos) continue;
						pos += 8;	///< !!! note hardcoded size of "charset=" string
						s1 = s1.substr(pos);
						// trim end of value
						pos = s1.find(';');
						if (pos != std::string::npos) s1=s1.substr(0,pos);
						pos = s1.find(' ');
						if (pos != std::string::npos) s1=s1.substr(0,pos);
						pos = s1.find('\"');
						if (pos != std::string::npos) s1=s1.substr(0,pos);
						// set as book encoding
						myDescription.encoding() = s1;
						fprintf(stderr,"HTML encoding: %s\n",s1.c_str());
						break;
					}
				}
				break;
			}
		}
	}
	return tag.Name != "BODY";
}

bool HtmlDescriptionReader::characterDataHandler(const char *text, int len, bool) {
	if (myReadTitle) {
		myDescription.title().append(text, len);
	}
	return true;
}
